package com.baizhi.security.filter;

import com.baizhi.security.exception.KaptchaNotMatchException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * ClassName: LoginKaptcha
 * Description: 自定义 filter
 * Date: 2022/11/05 PM 6:57
 * <p>
 * project: codes
 * package: com.baizhi.security.filter
 * email: 1085844536@qq.com
 * version:
 *
 * @author WangGuojian
 */
public class LoginKaptchaFilter extends UsernamePasswordAuthenticationFilter {

    private static final String FORM_KAPTCHA_KEY = "kaptcha";

    private String kaptchaParameter = FORM_KAPTCHA_KEY;

    public String getKaptchaParameter() {
        return kaptchaParameter;
    }

    public void setKaptchaParameter(String kaptchaParameter) {
        this.kaptchaParameter = kaptchaParameter;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (!"POST".equals(request.getMethod())) {
            throw new AuthenticationServiceException("Authentication method not allowed:" + request.getMethod());
        }
        // 1.获取请求验证码
        try {
            Map<String, String> userInfo = new ObjectMapper().readValue(request.getInputStream(),
                    Map.class);
            // 用户获取数据中的验证码
            String kaptcha = userInfo.get(getKaptchaParameter());
            // 用来接受用户名
            String username = userInfo.get(getUsernameParameter());
            // 用来接受密码
            String password = userInfo.get(getPasswordParameter());
            // 2.获取 session 中验证码
            String sessionVerifyCode = (String) request.getSession().getAttribute(getKaptchaParameter());
            if (!ObjectUtils.isEmpty(kaptcha) && !ObjectUtils.isEmpty(sessionVerifyCode) && !kaptcha.equalsIgnoreCase(sessionVerifyCode)) {
                // 3.获取用户名 和 密码认证
                UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
                return this.getAuthenticationManager().authenticate(authRequest);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        throw new KaptchaNotMatchException("验证码不匹配");
    }
}
